#include "../include/connection.h"
#include <cassert>
#include <unistd.h>

namespace net {

Connection::Connection(EventLoop* loop, uint64_t connId, int sockfd)
    : _connId(connId),
      _sockfd(sockfd),
      _enableInactiveRelease(false),
      _loop(loop),
      _statu(CONNECTING),
      _socket(new Socket(sockfd)),
      _channel(new Channel(loop, sockfd)) 
{
    // 绑定Channel的事件回调
    _channel->setCloseCallback(std::bind(&Connection::handleClose, this));
    _channel->setEventCallback(std::bind(&Connection::handleEvent, this));
    _channel->setReadCallback(std::bind(&Connection::handleRead, this));
    _channel->setWriteCallback(std::bind(&Connection::handleWrite, this));
    _channel->setErrorCallback(std::bind(&Connection::handleError, this));
    
    LOG_INFO("Connection constructor id= %lu , fd= %d", _connId, _sockfd);
}

Connection::~Connection() 
{
    LOG_INFO("Connection destructor id= %lu, fd= %d", _connId, _sockfd);
    if (_loop->hasTimer(_connId)) 
    {
        _loop->timerCancel(_connId); // 确保定时器被正确取消
    }
}

void Connection::established() 
{
    // 提交到事件循环线程执行初始化
    _loop->runInLoop(std::bind(&Connection::establishedInLoop, this));
}

void Connection::send(const char* data, size_t len) 
{
    if (len == 0 || _statu == DISCONNECTED) return;

    // 复制数据到临时缓冲区（避免外部数据失效）
    Buffer buf;
    buf.writeAndPush(data, len);
    // 提交发送任务到事件循环线程
    _loop->runInLoop(std::bind(&Connection::sendInLoop, this, std::move(buf)));
}

void Connection::shutdown() 
{
    if (_statu == DISCONNECTED || _statu == DISCONNECTING) return;
    _loop->runInLoop(std::bind(&Connection::shutdownInLoop, this));
}

void Connection::release() 
{
    if (_statu == DISCONNECTED) return;
    // 排队执行释放（避免重入）
    _loop->queueInLoop(std::bind(&Connection::releaseInLoop, this));
}

void Connection::enableInactiveRelease(int sec) 
{
    _loop->runInLoop(std::bind(&Connection::enableInactiveReleaseInLoop, this, sec));
}

void Connection::cancelInactiveRelease() 
{
    _loop->runInLoop(std::bind(&Connection::cancelInactiveReleaseInLoop, this));
}

void Connection::upgrade(const util::Any& context, 
                        const ConnectedCallback& conn, 
                        const MessageCallback& msg, 
                        const ClosedCallback& closed, 
                        const AnyEventCallback& event) 
{
    _loop->assertInLoop(); // 确保在事件循环线程执行
    _loop->runInLoop(std::bind(&Connection::upgradeInLoop, this, context, conn, msg, closed, event));
}

// 内部事件处理函数
void Connection::handleRead() 
{
    // 1. 非阻塞接收数据
    char buf[65536]; // 64KB临时缓冲区
    ssize_t ret = _socket->nonBlockRecv(buf, 65535); // 留1字节安全余量
    if (ret < 0) 
    {
        // 接收错误，触发关闭流程
        shutdownInLoop();
        return;
    }

    // 2. 数据写入输入缓冲区
    if (ret > 0) 
    {
        _inBuffer.writeAndPush(buf, ret);
    }

    // 3. 触发消息回调（若有数据）
    if (_inBuffer.readAbleSize() > 0 && _messageCallback) 
    {
        _messageCallback(shared_from_this(), &_inBuffer);
    }
}

void Connection::handleWrite() 
{
    // 发送输出缓冲区数据
    ssize_t ret = _socket->nonBlockSend(_outBuffer.readPosition(), _outBuffer.readAbleSize());
    if (ret < 0) 
    {
        // 发送错误，处理剩余数据后释放
        if (_inBuffer.readAbleSize() > 0 && _messageCallback) 
        {
            _messageCallback(shared_from_this(), &_inBuffer);
        }
        release();
        return;
    }

    // 移动读偏移（已发送数据）
    _outBuffer.moveReadOffset(ret);

    // 若缓冲区为空，关闭写事件监控
    if (_outBuffer.readAbleSize() == 0) 
    {
        _channel->disableWriting();
        // 若处于待关闭状态，此时释放连接
        if (_statu == DISCONNECTING) 
        {
            release();
        }
    }
}

void Connection::handleClose() 
{
    // 处理剩余数据后释放
    if (_inBuffer.readAbleSize() > 0 && _messageCallback) 
    {
        _messageCallback(shared_from_this(), &_inBuffer);
    }
    release();
}

void Connection::handleError() 
{
    // 错误事件直接触发关闭
    handleClose();
}

void Connection::handleEvent() 
{
    // 1. 刷新非活跃定时器（若启用）
    if (_enableInactiveRelease) 
    {
        _loop->timerRefresh(_connId);
    }
    // 2. 触发用户任意事件回调
    if (_eventCallback) 
    {
        _eventCallback(shared_from_this());
    }
}

// 内部实现函数（事件循环线程中执行）
void Connection::establishedInLoop() 
{
    assert(_statu == CONNECTING); // 确保状态正确
    _statu = CONNECTED;

    // 启动非活跃定时器（若已启用）
    if (_enableInactiveRelease) 
    {
        _loop->timerRefresh(_connId);
    }

    // 启动读事件监控（开始接收数据）
    _channel->tie(shared_from_this());
    _channel->enableReading();

    // 触发连接建立回调
    if (_connectedCallback) 
    {
        _connectedCallback(shared_from_this());
    }
}

void Connection::sendInLoop(Buffer& buf) 
{
    if (_statu == DISCONNECTED) return;

    _outBuffer.writeBufferAndPush(buf);
    if (!_channel->isWriting()) 
    {
        _channel->enableWriting();
    }
}

void Connection::shutdownInLoop() 
{
    if (_statu != CONNECTED) return;
    _statu = DISCONNECTING;
    
    if(_inBuffer.readAbleSize() && _messageCallback) 
    {
        _messageCallback(shared_from_this(), &_inBuffer);
    }

    // 启动写事件，等待数据发送完成
    if (_outBuffer.readAbleSize() && !_channel->isWriting()) 
    {
        _channel->enableWriting();
    }

    // 若输出缓冲区为空，直接释放
    if (_outBuffer.readAbleSize() == 0) 
    {
        release();
    }
}

void Connection::releaseInLoop() 
{
    if (_statu == DISCONNECTED) return;
    _statu = DISCONNECTED;

    // 1. 移除事件监控
    _channel->disableAll(); 
    _channel->remove();

    // 2. 关闭套接字
    _socket->close();

    // 3. 取消非活跃定时器
    if (_loop->hasTimer(_connId)) 
    {
        _loop->timerCancel(_connId);
    }

    // 4. 触发用户层关闭回调
    if (_closedCallback) 
    {
        _closedCallback(shared_from_this());
    }

    // 5. 触发框架层关闭回调（移除连接管理）
    if (_serverClosedCallback) 
    {
        _serverClosedCallback(shared_from_this());
    }
}

void Connection::enableInactiveReleaseInLoop(int sec) 
{
    _enableInactiveRelease = true;

    // 刷新或添加定时器（超时后释放）
    if (_loop->hasTimer(_connId)) 
    {
        _loop->timerRefresh(_connId);
    } 
    else 
    {
        _loop->timerAdd(_connId, sec, std::bind(&Connection::release, this));
    }
}

void Connection::cancelInactiveReleaseInLoop() 
{
    _enableInactiveRelease = false;
    if (_loop->hasTimer(_connId)) 
    {
        _loop->timerCancel(_connId);
    }
}

void Connection::upgradeInLoop(const util::Any& context, 
                             const ConnectedCallback& conn, 
                             const MessageCallback& msg, 
                             const ClosedCallback& closed, 
                             const AnyEventCallback& event) 
{
    // 更新上下文和回调函数（协议切换）
    _context = context;
    _connectedCallback = conn;
    _messageCallback = msg;
    _closedCallback = closed;
    _eventCallback = event;
}

} // namespace net